<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.2">
<title>OSGi</title>
<link rel="stylesheet" href="./css/hibernate.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js"></script>
<script>document.addEventListener('DOMContentLoaded', prettyPrint)</script>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="sect1">
<h2 id="osgi">OSGi</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_osgi_specification_and_environment">OSGi Specification and Environment</h3>
<div class="paragraph">
<p>Hibernate targets the OSGi 4.3 spec or later.
It was necessary to start with 4.3, over 4.2, due to our dependency on OSGi&#8217;s <code>BundleWiring</code> for entity/mapping scanning.</p>
</div>
<div class="paragraph">
<p>Hibernate supports three types of configurations within OSGi.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Container-Managed JPA <a href="#osgi-managed-jpa">Container-Managed JPA</a></p>
</li>
<li>
<p>Unmanaged JPA <a href="#osgi-unmanaged-jpa">Unmanaged JPA</a></p>
</li>
<li>
<p>Unmanaged Native <a href="#osgi-unmanaged-native">Unmanaged Native</a></p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="_hibernate_osgi">hibernate-osgi</h3>
<div class="paragraph">
<p>Rather than embed OSGi capabilities into hibernate-core, and sub-modules, hibernate-osgi was created.
It&#8217;s purposefully separated, isolating all OSGi dependencies.
It provides an OSGi-specific <code>ClassLoader</code> (aggregates the container&#8217;s <code>ClassLoader</code> with core and <code>EntityManager</code> <code>ClassLoader`s),
JPA persistence provider, `SessionFactory</code>/<code>EntityManagerFactory</code> bootstrapping, entities/mappings scanner, and service management.</p>
</div>
</div>
<div class="sect2">
<h3 id="_features_xml">features.xml</h3>
<div class="paragraph">
<p>Apache Karaf environments tend to make heavy use of its "features" concept, where a feature is a set of order-specific bundles focused on a concise capability.
These features are typically defined in a <code>features.xml</code> file.
Hibernate produces and releases its own <code>features.xml</code> that defines a core <code>hibernate-orm</code>, as well as additional features for optional functionality (caching, Envers, etc.).
This is included in the binary distribution, as well as deployed to the JBoss Nexus repository (using the <code>org.hibernate</code> groupId and <code>hibernate-osgi</code> with the <code>karaf.xml</code> classifier).</p>
</div>
<div class="paragraph">
<p>Note that our features are versioned using the same ORM artifact versions they wrap.
Also, note that the features are heavily tested against Karaf 3.0.3 as a part of our PaxExam-based integration tests.
However, they&#8217;ll likely work on other versions as well.</p>
</div>
<div class="paragraph">
<p>hibernate-osgi, theoretically, supports a variety of OSGi containers, such as Equinox.
In that case, please use `features.xm`l as a reference for necessary bundles to activate and their correct ordering.
However, note that Karaf starts a number of bundles automatically, several of which would need to be installed manually on alternatives.</p>
</div>
</div>
<div class="sect2">
<h3 id="_quickstarts_demos">QuickStarts/Demos</h3>
<div class="paragraph">
<p>All three configurations have a QuickStart/Demo available in the <a href="https://github.com/hibernate/hibernate-demos">hibernate-demos</a> project:</p>
</div>
</div>
<div class="sect2">
<h3 id="osgi-managed-jpa">Container-Managed JPA</h3>
<div class="paragraph">
<p>The Enterprise OSGi specification includes container-managed JPA.
The container is responsible for discovering persistence units in bundles and automatically creating the <code>EntityManagerFactory</code> (one <code>EntityManagerFactory</code> per <code>PersistenceUnit</code>).
It uses the JPA provider (hibernate-osgi) that has registered itself with the OSGi <code>PersistenceProvider</code> service.</p>
</div>
</div>
<div class="sect2">
<h3 id="_enterprise_osgi_jpa_container">Enterprise OSGi JPA Container</h3>
<div class="paragraph">
<p>In order to utilize container-managed JPA, an Enterprise OSGi JPA container must be active in the runtime.
In Karaf, this means Aries JPA, which is included out-of-the-box (simply activate the <code>jpa</code> and <code>transaction</code> features).
Originally, we intended to include those dependencies within our own <code>features.xml</code>.
However, after guidance from the Karaf and Aries teams, it was pulled out.
This allows Hibernate OSGi to be portable and not be directly tied to Aries versions, instead having the user choose which to use.</p>
</div>
<div class="paragraph">
<p>That being said, the QuickStart/Demo projects include a sample <a href="https://github.com/hibernate/hibernate-demos/tree/master/hibernate-orm/osgi/managed-jpa/features.xml">features.xml</a>
showing which features need activated in Karaf in order to support this environment.
As mentioned, use this purely as a reference!</p>
</div>
</div>
<div class="sect2">
<h3 id="_persistence_xml">persistence.xml</h3>
<div class="paragraph">
<p>Similar to any other JPA setup, your bundle must include a <code>persistence.xml</code> file. This is typically located in <code>META-INF</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_datasource">DataSource</h3>
<div class="paragraph">
<p>Typical Enterprise OSGi JPA usage includes a <code>DataSource</code> installed in the container.
Your bundle&#8217;s <code>persistence.xml</code> calls out the <code>DataSource</code> through JNDI.
For example, you could install the following H2 <code>DataSource</code>.
You can deploy the <code>DataSource</code> manually (Karaf has a <code>deploy</code> dir), or through a "blueprint bundle" (<code>blueprint:file:/[PATH]/datasource-h2.xml</code>).</p>
</div>
<div class="exampleblock">
<div class="title">Example 1. datasource-h2.xml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!--
First install the H2 driver using:
&gt; install -s mvn:com.h2database/h2/1.3.163

Then copy this file to the deploy folder
--&gt;
&lt;blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"&gt;

    &lt;bean id="dataSource" class="org.h2.jdbcx.JdbcDataSource"&gt;
        &lt;property name="URL" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/&gt;
        &lt;property name="user" value="sa"/&gt;
        &lt;property name="password" value=""/&gt;
    &lt;/bean&gt;

    &lt;service interface="javax.sql.DataSource" ref="dataSource"&gt;
        &lt;service-properties&gt;
            &lt;entry key="osgi.jndi.service.name" value="jdbc/h2ds"/&gt;
        &lt;/service-properties&gt;
    &lt;/service&gt;
&lt;/blueprint&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>That <code>DataSource</code> is then used by your <code>persistence.xml</code> persistence-unit. The following works in Karaf, but the names may need tweaked in alternative containers.</p>
</div>
<div class="exampleblock">
<div class="title">Example 2. META-INF/persistence.xml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;jta-data-source&gt;osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/h2ds)&lt;/jta-data-source&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_bundle_package_imports">Bundle Package Imports</h3>
<div class="paragraph">
<p>Your bundle&#8217;s manifest will need to import, at a minimum,</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>javax.persistence</code></p>
</li>
<li>
<p><code>org.hibernate.proxy</code> and <code>javassist.util.proxy</code>, due to Hibernate&#8217;s ability to return proxies for lazy initialization (Javassist enhancement occurs on the entity&#8217;s <code>ClassLoader</code> during runtime).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_obtaining_an_entitymanger">Obtaining an EntityManger</h3>
<div class="paragraph">
<p>The easiest, and most supported, method of obtaining an <code>EntityManager</code> utilizes OSGi&#8217;s <code>OSGI-INF/blueprint/blueprint.xml</code> in your bundle.
The container takes the name of your persistence unit, then automatically injects an <code>EntityManager</code> instance into your given bean attribute.</p>
</div>
<div class="exampleblock">
<div class="title">Example 3. OSGI-INF/blueprint/blueprint.xml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;blueprint xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
           xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
           default-activation="eager"
           xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"&gt;

    &lt;!-- This gets the container-managed EntityManager and injects it into the DataPointServiceImpl bean.
    Assumes DataPointServiceImpl has an "entityManager" field with a getter and setter. --&gt;
    &lt;bean id="dpService" class="org.hibernate.osgitest.DataPointServiceImpl"&gt;
        &lt;jpa:context unitname="managed-jpa" property="entityManager"/&gt;
        &lt;tx:transaction method="*" value="Required"/&gt;
    &lt;/bean&gt;

    &lt;service ref="dpService" interface="org.hibernate.osgitest.DataPointService"/&gt;

&lt;/blueprint&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="osgi-unmanaged-jpa">Unmanaged JPA</h3>
<div class="paragraph">
<p>Hibernate also supports the use of JPA, unmanaged by the OSGi container.
The client bundle is responsible for managing the <code>EntityManagerFactory</code> and `EntityManager`s.</p>
</div>
</div>
<div class="sect2">
<h3 id="_persistence_xml_2">persistence.xml</h3>
<div class="paragraph">
<p>Similar to any other JPA setup, your bundle must include a <code>persistence.xml</code> file. This is typically located in <code>META-INF</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_bundle_package_imports_2">Bundle Package Imports</h3>
<div class="paragraph">
<p>Your bundle&#8217;s manifest will need to import, at a minimum,</p>
</div>
<div class="ulist">
<ul>
<li>
<p>javax.persistence</p>
</li>
<li>
<p><code>org.hibernate.proxy</code> and <code>javassist.util.proxy</code>, due to Hibernate&#8217;s ability to return proxies for lazy initialization (Javassist enhancement occurs on the entity&#8217;s <code>ClassLoader</code> during runtime)</p>
</li>
<li>
<p>JDBC driver package (example: <code>org.h2</code>)</p>
</li>
<li>
<p><code>org.osgi.framework</code>, necessary to discover the <code>EntityManagerFactory</code> (described below)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_obtaining_an_entitymangerfactory">Obtaining an EntityMangerFactory</h3>
<div class="paragraph">
<p><code>hibernate-osgi</code> registers an OSGi service, using the JPA <code>PersistenceProvider</code> interface name, that bootstraps and creates an <code>EntityManagerFactory</code> specific for OSGi environments.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is VITAL that your <code>EntityManagerFactory</code> be obtained through the service, rather than creating it manually.
The service handles the OSGi <code>ClassLoader</code>, discovered extension points, scanning, etc.
Manually creating an <code>EntityManagerFactory</code> is guaranteed to NOT work during runtime!</p>
</div>
</td>
</tr>
</table>
</div>
<div class="exampleblock">
<div class="title">Example 4. Discover/Use <code>EntityManagerFactory</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class HibernateUtil {

    private EntityManagerFactory emf;

    public EntityManager getEntityManager() {
        return getEntityManagerFactory().createEntityManager();
    }

    private EntityManagerFactory getEntityManagerFactory() {
        if ( emf == null ) {
            Bundle thisBundle = FrameworkUtil.getBundle( HibernateUtil.class );
            BundleContext context = thisBundle.getBundleContext();

            ServiceReference serviceReference = context.getServiceReference( PersistenceProvider.class.getName() );
            PersistenceProvider persistenceProvider = ( PersistenceProvider ) context.getService( serviceReference );

            emf = persistenceProvider.createEntityManagerFactory( "YourPersistenceUnitName", null );
        }
        return emf;
    }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="osgi-unmanaged-native">Unmanaged Native</h3>
<div class="paragraph">
<p>Native Hibernate use is also supported. The client bundle is responsible for managing the <code>SessionFactory</code> and `Session`s.</p>
</div>
</div>
<div class="sect2">
<h3 id="_bundle_package_imports_3">Bundle Package Imports</h3>
<div class="paragraph">
<p>Your bundle&#8217;s manifest will need to import, at a minimum,</p>
</div>
<div class="ulist">
<ul>
<li>
<p>javax.persistence</p>
</li>
<li>
<p><code>org.hibernate.proxy</code> and <code>javassist.util.proxy</code>, due to Hibernate&#8217;s ability to return proxies for lazy initialization (Javassist enhancement occurs on the entity&#8217;s <code>ClassLoader</code> during runtime)</p>
</li>
<li>
<p>JDBC driver package (example: <code>org.h2</code>)</p>
</li>
<li>
<p><code>org.osgi.framework</code>, necessary to discover the <code>SessionFactory</code> (described below)</p>
</li>
<li>
<p><code>org.hibernate.*</code> packages, as necessary (ex: cfg, criterion, service, etc.)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_obtaining_an_sessionfactory">Obtaining an SessionFactory</h3>
<div class="paragraph">
<p><code>hibernate-osgi</code> registers an OSGi service, using the <code>SessionFactory</code> interface name, that bootstraps and creates a <code>SessionFactory</code> specific for OSGi environments.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is VITAL that your <code>SessionFactory</code> be obtained through the service, rather than creating it manually. The service handles the OSGi <code>ClassLoader</code>, discovered extension points, scanning, etc.
Manually creating a <code>SessionFactory</code> is guaranteed to NOT work during runtime!</p>
</div>
</td>
</tr>
</table>
</div>
<div class="exampleblock">
<div class="title">Example 5. Discover/Use <code>SessionFactory</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class HibernateUtil {

    private SessionFactory sf;

    public Session getSession() {
        return getSessionFactory().openSession();
    }

    private SessionFactory getSessionFactory() {
        if ( sf == null ) {
            Bundle thisBundle = FrameworkUtil.getBundle( HibernateUtil.class );
            BundleContext context = thisBundle.getBundleContext();

            ServiceReference sr = context.getServiceReference( SessionFactory.class.getName() );
            sf = ( SessionFactory ) context.getService( sr );
        }
        return sf;
    }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_optional_modules">Optional Modules</h3>
<div class="paragraph">
<p>The <a href="https://github.com/hibernate/hibernate-demos/tree/master/hibernate-orm/osgi/unmanaged-native">unmanaged-native</a> demo project displays the use of optional Hibernate modules.
Each module adds additional dependency bundles that must first be activated, either manually or through an additional feature.
As of ORM 4.2, Envers is fully supported.
Support for C3P0, Proxool, EhCache, and Infinispan were added in 4.3, however none of their 3rd party libraries currently work in OSGi (lots of <code>ClassLoader</code> problems, etc.).
We&#8217;re tracking the issues in JIRA.</p>
</div>
</div>
<div class="sect2">
<h3 id="_extension_points">Extension Points</h3>
<div class="paragraph">
<p>Multiple contracts exist to allow applications to integrate with and extend Hibernate capabilities.
Most apps utilize JDK services to provide their implementations.
<code>hibernate-osgi</code> supports the same extensions through OSGi services.
Implement and register them in any of the three configurations.
<code>hibernate-osgi</code> will discover and integrate them during <code>EntityManagerFactory</code>/<code>SessionFactory</code> bootstrapping. Supported extension points are as follows.
The specified interface should be used during service registration.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>org.hibernate.integrator.spi.Integrator</code></dt>
<dd>
<p>(as of 4.2)</p>
</dd>
<dt class="hdlist1"><code>org.hibernate.boot.registry.selector.StrategyRegistrationProvider</code></dt>
<dd>
<p>(as of 4.3)</p>
</dd>
<dt class="hdlist1"><code>org.hibernate.boot.model.TypeContributor</code></dt>
<dd>
<p>(as of 4.3)</p>
</dd>
<dt class="hdlist1">JTA&#8217;s</dt>
<dd>
<p><code>javax.transaction.TransactionManager</code> and <code>javax.transaction.UserTransaction</code> (as of 4.2), however these are typically provided by the OSGi container.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The easiest way to register extension point implementations is through a <code>blueprint.xml</code> file.
Add <code>OSGI-INF/blueprint/blueprint.xml</code> to your classpath. Envers' blueprint is a great example:</p>
</div>
<div class="exampleblock">
<div class="title">Example 6. Example extension point registrations in blueprint.xml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or &lt;http://www.gnu.org/licenses/lgpl-2.1.html&gt;.
  --&gt;
&lt;blueprint default-activation="eager"
           xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"&gt;

    &lt;bean id="integrator" class="org.hibernate.envers.boot.internal.EnversIntegrator"/&gt;
    &lt;service ref="integrator" interface="org.hibernate.integrator.spi.Integrator"/&gt;

    &lt;bean id="typeContributor"
          class="org.hibernate.envers.boot.internal.TypeContributorImpl"/&gt;
    &lt;service ref="typeContributor" interface="org.hibernate.boot.model.TypeContributor"/&gt;

&lt;/blueprint&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Extension points can also be registered programmatically with <code>BundleContext#registerService</code>, typically within your <code>BundleActivator#start</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_caveats">Caveats</h3>
<div class="ulist">
<ul>
<li>
<p>Technically, multiple persistence units are supported by Enterprise OSGi JPA and unmanaged Hibernate JPA use.
However, we cannot currently support this in OSGi.
In Hibernate 4, only one instance of the OSGi-specific <code>ClassLoader</code> is used per Hibernate bundle, mainly due to heavy use of static TCCL utilities.
We hope to support one OSGi <code>ClassLoader</code> per persistence unit in Hibernate 5.</p>
</li>
<li>
<p>Scanning is supported to find non-explicitly listed entities and mappings.
However, they MUST be in the same bundle as your persistence unit (fairly typical anyway).
Our OSGi <code>ClassLoader</code> only considers the "requesting bundle" (hence the requirement on using services to create <code>EntityManagerFactory</code>/<code>SessionFactory</code>), rather than attempting to scan all available bundles.
This is primarily for versioning considerations, collision protections, etc.</p>
</li>
<li>
<p>Some containers (ex: Aries) always return true for <code>PersistenceUnitInfo#excludeUnlistedClasses</code>, even if your <code>persistence.xml</code> explicitly has <code>exclude-unlisted-classes</code> set to <code>false</code>.
They claim it&#8217;s to protect JPA providers from having to implement scanning ("we handle it for you"), even though we still want to support it in many cases.
The work around is to set <code>hibernate.archive.autodetection</code> to, for example, <code>hbm,class</code>.
This tells hibernate to ignore the <code>excludeUnlistedClasses</code> value and scan for <code>*.hbm.xml</code> and entities regardless.</p>
</li>
<li>
<p>Scanning does not currently support annotated packages on <code>package-info.java</code>.</p>
</li>
<li>
<p>Currently, Hibernate OSGi is primarily tested using Apache Karaf and Apache Aries JPA. Additional testing is needed with Equinox, Gemini, and other container providers.</p>
</li>
<li>
<p>Hibernate ORM has many dependencies that do not currently provide OSGi manifests. The QuickStart tutorials make heavy use of 3rd party bundles (SpringSource, ServiceMix) or the <code>wrap:&#8230;&#8203;</code> operator.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-04-05 16:05:02 +02:00
</div>
</div>
</body>
</html>